package com.bumptech.glide.load.data;

import com.bumptech.glide.Priority;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.util.LogUtil;
import ohos.app.Context;
import ohos.utils.net.Uri;
import org.jetbrains.annotations.NotNull;

import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * A DataFetcher that uses a context to load data from a {@link ohos.utils.net.Uri} pointing to a local resource.
 *
 * @param <T> The type of data that will obtained for the given uri (For example, {@link
 *     java.io.InputStream}
 */
public abstract class LocalUriFetcher<T> implements DataFetcher<T> {
  private static final String TAG = "LocalUriFetcherH";
  private final Uri uri;
  private final Context context;
  private T data;

  /**
   * Opens an input stream for a uri pointing to a local asset. Only certain uris are supported
   *
   * @param context Any context.
   * @param uri A Uri pointing to a local asset. This load will fail if the uri isn't openable by
   *     openInputStream(ohos.utils.net.Uri)
   */
  // Public API.
  @SuppressWarnings("WeakerAccess")
  public LocalUriFetcher(Context context, Uri uri) {
    this.context = context;
    this.uri = uri;
  }

  @Override
  public final void loadData(
          @NotNull Priority priority, @NotNull DataCallback<? super T> callback) {
    try {
      data = loadResource(uri, context);
    } catch (FileNotFoundException e) {
      if (LogUtil.isLoggable(TAG, LogUtil.DEBUG)) {
        LogUtil.info(TAG, "Failed to open Uri");
      }
      callback.onLoadFailed(e);
      return;
    }
    callback.onDataReady(data);
  }

  @Override
  public void cleanup() {
    if (data != null) {
      try {
        close(data);
      } catch (IOException e) {
        // Ignored.
      }
    }
  }

  @Override
  public void cancel() {
    // Do nothing.
  }

  @NotNull
  @Override
  public DataSource getDataSource() {
    return DataSource.LOCAL;
  }

  /**
   * Returns a concrete data type from the given {@link ohos.utils.net.Uri} using the given {@link
   * Context context}.
   * @param context
   * @param uri
   * @throws FileNotFoundException
   * @return t
   * @throws FileNotFoundException
   */
  protected abstract T loadResource(Uri uri, Context context)
      throws FileNotFoundException;


  /**
   * Closes the concrete data type if necessary.
   *
   * <p>Note - We can't rely on the closeable interface because it was added after our min API
   * level. See issue #157.
   *
   * @param data The data to close.
   * @throws IOException
   */
  protected abstract void close(T data) throws IOException;
}
